package UI;

import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Insets;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import java.io.File;
import java.util.ArrayList;

import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.filechooser.FileSystemView;

import client.ClientDirectory;
import client.MessageHandler;
import dataContracts.InstallSettings;

public class UI implements MouseListener {

	private JFrame frame = new JFrame();
	private Component active = null;
	private ClientDirectory clientDirectory;
	
	MessageHandler messageHandler;
	
	ArrayList<File> files = new ArrayList<File>();
	
	//CONSTANTS
	private static final int WIDTH = 900;
	private static final int HEIGHT = 650;
	private static final Color bgCOLOR = new Color(239,240,240);
	private static final Color pgCOLOR = new Color(229,230,230);
	
	//COMMUNICATION OBJECTS
	public JTextArea serverLogTextBox;
	public JTextField broadcastText;
	public JMenu sync;
	public JButton syncButton;
	
	public static void run() {
		
		try {
		 for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
		        if ("Nimbus".equals(info.getName())) {
		            UIManager.setLookAndFeel(info.getClassName());
		            break;
		        }
		    }
		} catch (Exception e) {
			try {
				UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
			} catch (ClassNotFoundException e1) {
				e1.printStackTrace();
			} catch (InstantiationException e1) {
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				e1.printStackTrace();
			} catch (UnsupportedLookAndFeelException e1) {
				e1.printStackTrace();
			}
		}
	
	}
	
    public UI(MessageHandler msgHandler, ClientDirectory clientDirectory) {
    	//do the awkward message handler initialization dance
    	messageHandler = msgHandler;
    	messageHandler.ui = this;
    	//at this point we have an object to which we will delegate all server communication
    	//to add a new method call, just add an actionListener to the MessageHandler class
    	//and that actionListener has access to both this UI and the ClientProgram class which does the socket I/O
    	
        ImageIcon logoIcon = normButton(new ImageIcon("images/lyLogo.png"));
    	GridBagConstraints c;
        
    	//Application Attributes
        frame.setSize(WIDTH,HEIGHT);
        frame.setLayout(new GridBagLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setIconImage(logoIcon.getImage());
        frame.setTitle("LANyard");
        frame.setJMenuBar(initMenuBar());	//add menu bar
        
        //TOOLBAR
        //CONSTRAINT: x = 0, y = 0, weightx = 1, weighty = 0, ancor = northwest, margin = 2, fill = horizontal
        c = setConstraints(0,0,1,0,GridBagConstraints.NORTHWEST, new Insets(2,2,2,2), GridBagConstraints.HORIZONTAL);
        frame.getContentPane().add(initToolBar(), c);
        
        //SPLITPANE
        //CONSTRAINT: x: 0, y: 0, weightx; 1, weighty: 0, ancor: north, margin: 3, fill: all
        c = setConstraints(0,1,1,1,GridBagConstraints.NORTH, new Insets(3,3,3,3), GridBagConstraints.BOTH);
        frame.getContentPane().add(initSplitPane(), c);
        
        frame.setVisible(true);

    }
    
    //COMPONENT BUILDERS
    
    //MENU BAR
    private JMenuBar initMenuBar(){
		
    	JMenuItem item;
    	JMenuBar menuBar;
    	int shortCutMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
 
    	//core element
        menuBar = new JMenuBar();
        
        //file menu
        JMenu file = new JMenu("File");
        file.setMnemonic('F');
        	//exit Item (cmd-x)
        	item = new JMenuItem("Exit");
        	item.setAccelerator(KeyStroke.getKeyStroke('x', shortCutMask));
        	item.setMnemonic('x');
        	file.add(item);
        
        //edit menu
        JMenu edit = new JMenu("Edit");
        edit.setMnemonic('E');
        //copy Item (cmd-c)
    		item = new JMenuItem("Copy");
    		item.setAccelerator(KeyStroke.getKeyStroke('C', shortCutMask, false));
    		item.setMnemonic('C');
    		edit.add(item);
    	//paste Item (cmd-p)
       		item = new JMenuItem("Paste");
    		item.setAccelerator(KeyStroke.getKeyStroke('P', shortCutMask, false));
    		item.setMnemonic('P');
    		edit.add(item);
    		
        
        sync = new JMenu("Sync");
        sync.setMnemonic('y');
        //sync item (cmd-s)
       		item = new JMenuItem("Sync");
			item.setAccelerator(KeyStroke.getKeyStroke('S', shortCutMask, false));
			item.setMnemonic('S');
			sync.add(item);        
        
        JMenu help = new JMenu("Help");	   
        help.setMnemonic('H');
        //about item (cmd-a)	
        	item = new JMenuItem("About");
			item.setAccelerator(KeyStroke.getKeyStroke('A', shortCutMask, false));
			item.setMnemonic('A');
			help.add(item);
        //help item (cmd-h)
        	item = new JMenuItem("Help");
			item.setAccelerator(KeyStroke.getKeyStroke('H', shortCutMask, false));
			item.setMnemonic('H');
			help.add(item);
        
		//add to bar	
        menuBar.add(file);
        menuBar.add(edit);
        menuBar.add(sync);
        menuBar.add(help);
    	
    	return menuBar;
    	
    }
    
    //TOOLBAR
    private JToolBar initToolBar(){
        
    	final int margin = 2;		//for toolbar margin 
    	
    	//Icon instantiations
        ImageIcon syncIcon = normButton(new ImageIcon("images/sync.png"));
        ImageIcon trash = normButton(new ImageIcon("images/trash.png"));
        
        //BAR
    	JToolBar toolBar = new JToolBar();
    	//Bar Attributes
    		toolBar.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0));
        	toolBar.setMargin(new Insets(margin, margin, margin, margin));
        	toolBar.setFloatable(false);
        	toolBar.setSize(WIDTH, 0);
    	
    	//Sync Button
        syncButton = new JButton();
        //Sync Button attributes
        	syncButton.setIcon(syncIcon);
        	syncButton.setRolloverEnabled(true);
        	syncButton.setToolTipText("Sync");

        //Trash Button
        JButton trashButton = new JButton();
        	trashButton.setIcon(trash);
        	trashButton.setRolloverEnabled(true);
        	trashButton.setToolTipText("Trash");
        	
        //add the items	
        toolBar.add(syncButton);
        toolBar.add(trashButton);
        toolBar.addSeparator();
        
        return toolBar;
    
    }
    
    //SPLIT PANE
    private JSplitPane initSplitPane(){
    	
    	JSplitPane splitPane; 
    	
    	splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, initLeftPane(), initRightPane());
    		splitPane.setOneTouchExpandable(true);
    		splitPane.setDividerLocation(WIDTH-350);
    	
    	return splitPane;
    	
    }
    
    //LEFT PANE (
    private JScrollPane initLeftPane(){
    	
    	JScrollPane pane; 
    	JPanel panel;
    	GridBagConstraints c;
    	
    	panel = new JPanel(new GridBagLayout());
			panel.setBackground(bgCOLOR);
			panel.setBorder(BorderFactory.createTitledBorder("Files"));
		
		//For each file in the collection, add a file panel
		InstallSettings is = new InstallSettings();
		System.out.println(is.directoryPath);
	    File dir = new File(is.directoryPath);
        c = setConstraints(0, 0, 1, 0, GridBagConstraints.NORTHWEST, new Insets(2, 2, 2, 2), GridBagConstraints.HORIZONTAL);
        c.gridwidth = GridBagConstraints.REMAINDER;
	    
        traverseDirectory(dir);
    /*    
        for(File f : files){
        	System.out.println(f.getName());
        }
    */    
	    for(File f : files){
	    	panel.add(initFileEntry(f), c);
	    	c.gridy++;
	    	c.weighty++;
		} 
	    
	    
		/*FOR TESTING ONLY DROP A DOC FILE
		//panel 1
		File f = new File("docs/SRS/SRS v1.0.docx");
        c = setConstraints(0, 0, 1, 0, GridBagConstraints.NORTHWEST, new Insets(2, 2, 2, 2), GridBagConstraints.HORIZONTAL);
        c.gridwidth = GridBagConstraints.REMAINDER;
        panel.add(initFileEntry(f),c);
    	
        f = new File("images/sync.png");
        c.gridy++;	//next row
        c.weighty++;
        panel.add(initFileEntry(f),c);
            
        END TEST SECTION */
		
    	pane = new JScrollPane(panel);

    	return pane;
    	
    }
    
    //RIGHT PANEL (FILE INFORMATION)
    private JScrollPane initRightPane(){
    	
    	JScrollPane pane;
    	JPanel panel;
    	GridBagConstraints c;
    	
    	String[] labels = {"File Name:", "Owner:","Project:","Tags:", "Comments:"};
    	
    	panel = new JPanel(new GridBagLayout());
    		panel.setBackground(bgCOLOR);
    		panel.setBorder(BorderFactory.createTitledBorder("File Information"));
    	
    	//LABELS
    	c = setConstraints(0, 0, 0, 0, GridBagConstraints.NORTHWEST, new Insets(5, 5, 5, 5), GridBagConstraints.HORIZONTAL);
    	c.gridwidth = 1;

    	for(int i = 0; i < labels.length; i++){
        	panel.add(new JLabel(labels[i]), c);
        	c.gridy++;	//next row
    	}
    	
    	//Comments Label
    	panel.add(new JLabel("Comments:"), c);
    	
    	//METADATA TEXTAREAS
    	c = setConstraints(1, 0, 1, 0, GridBagConstraints.NORTHWEST, new Insets(1, 1, 1, 1), GridBagConstraints.HORIZONTAL);
    	c.gridwidth = GridBagConstraints.REMAINDER;
    	
    	for(int i = 0; i < labels.length; i++){
        	
    		panel.add(new JTextField(), c);
        	c.gridy++;
    	}

    	//Comments TextArea
    	c.weighty = 1;
    	JTextArea comments = new JTextArea(5,0);
    	comments.setLineWrap(true);
    	comments.setMargin(new Insets(5,5,5,5));
    	panel.add(comments, c);
    	
    	//Broadcast a message to all clients online
    	c.gridy++;
    	c.gridx--;
    	JLabel broadcastLabel = new JLabel("Message:");
    	panel.add(broadcastLabel, c);
    	
    	c.gridx++;
    	broadcastText = new JTextField();
    	panel.add(broadcastText, c);
    	
    	c.gridy++;
    	c.gridx--;
    	JButton broadcastButton = new JButton("Send");
    	broadcastButton.addActionListener(messageHandler.new Broadcast());
    	panel.add(broadcastButton, c);
    	
    	//Server Log TextArea
    	c.weighty= 1;
    	c.gridy++;
    	c.gridx--;
    	panel.add(new JLabel("Server Log:"), c);
    	
    	c.gridx++;
    	serverLogTextBox = new JTextArea(15, 0);
    	panel.add(serverLogTextBox, c);
    	
    	pane = new JScrollPane(panel);
    	
    	return pane;
    }
    
    private JPanel initFileEntry(File f){
		
    	JPanel panel;
    	GridBagConstraints c;
    	
    	panel = new JPanel(new GridBagLayout());
    	panel.addMouseListener(this);
    	//panel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
    	
    	Icon icon = FileSystemView.getFileSystemView().getSystemIcon(f);
    	
        c = setConstraints(0, 0, 1, 0, GridBagConstraints.NORTHWEST, new Insets(20, 20, 20, 20), 0);            
        long size = f.length() / 1024;
        
        panel.setBackground(pgCOLOR);
        panel.add(new JLabel(icon), c);
        
        c.gridx++;	//next column
        c.anchor = GridBagConstraints.WEST;
        c.weightx++;
        c.insets = new Insets(0,0,0,0);
        panel.add(new JLabel(f.getName()),c);
        
        c.gridx++; //next col
        c.weightx++;
        c.anchor = GridBagConstraints.EAST;
        c.insets = new Insets(3,3,3,3);
        panel.add(new JLabel(""+size+"KB "), c);
    	
        panel.setName(f.getAbsolutePath());						//This will have to be a unique identifier for the file displayed on the panel
        
    	return panel;
    	
    }
    
    //HELPER METHODS
    
    private ImageIcon normButton(ImageIcon i){
		
        Image image = i.getImage().getScaledInstance(20,20,Image.SCALE_SMOOTH);
        i.setImage(image);    	
    	return i;
    	
    }
    
    public void servLog(String msg){
    	serverLogTextBox.setText(serverLogTextBox.getText() + msg + "\n");
    }
    
    public void traverseDirectory(File dir){

    	if (dir.isDirectory()){
    		String[] children = dir.list();
    		for(int i = 0; i<children.length; i++){
    			traverseDirectory(new File(dir, children[i]));
    		} 
    	} else if (!dir.isHidden()){
    			files.add(dir.getAbsoluteFile());
    	}
		
    }
    
    private GridBagConstraints setConstraints(int x, int y, int wx, int wy, int a, Insets i, int fill){
		
    	GridBagConstraints c = new GridBagConstraints();
    	
    	c.gridx = x;
    	c.gridy = y;
    	c.weightx = wx;
    	c.weighty = wy;
    	c.anchor = a;
    	c.insets = i;
    	c.fill = fill;
    	
    	return c;
 
    }

	@Override
	public void mouseClicked(MouseEvent e) {
		
		if(active == null){	
			active = e.getComponent();						//store the value
			active.setBackground(new Color(200,230,230));	//highlight the panel
			
		} else if(!active.equals(e.getComponent())){
			active.setBackground(pgCOLOR);					//reset color on previous selection
			active = e.getComponent();						//replace "active" component
			active.setBackground(new Color(200,230,230));	//highlight the panel
		}
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
    
}